package org.linlinjava.litemall.admin.service;

import com.alibaba.druid.support.json.JSONUtils;
import com.github.pagehelper.util.StringUtil;
import org.linlinjava.litemall.admin.dto.BusinessResultDetail;
import org.linlinjava.litemall.admin.util.AdminCheck;
import org.linlinjava.litemall.admin.util.AdminStringUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.YwcgEnumUtil;
import org.linlinjava.litemall.db.domain.BusinessPerson;
import org.linlinjava.litemall.db.domain.BusinessProject;
import org.linlinjava.litemall.db.domain.BusinessResult;
import org.linlinjava.litemall.db.domain.ProjectFile;
import org.linlinjava.litemall.db.service.BusinessPersonService;
import org.linlinjava.litemall.db.service.BusinessProjectService;
import org.linlinjava.litemall.db.service.BusinessResultService;
import org.linlinjava.litemall.db.service.ProjectFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @Author: Daisen.Z
 * @Date: 2021/6/6 12:55
 * @Version: 1.0
 * @Description:
 */
@Service
public class AdBusinessResultService {

    @Autowired
    private BusinessPersonService personService;

    @Autowired
    private BusinessResultService businessResultService;

    @Autowired
    private BusinessProjectService businessProjectService;

    @Autowired
    private ProjectFileService projectFileService;

    @Autowired
    private AdBusinessAuditService adBusinessAuditService;



    public Object querySelective(String year, String name, String resMark, String projectName, Integer modelId,Integer statusAudit,
                                 String dutyPeopleName,Integer page, Integer limit, String sort, String order) {
        String peopleName = AdminCheck.isSuperUser();

        BusinessResult businessResultParam = new BusinessResult();
        businessResultParam.setResName(name);
        businessResultParam.setResYear(year);
        businessResultParam.setResMark(resMark);
        businessResultParam.setResWithProjectName(projectName);
        businessResultParam.setOwningModule(modelId);
        businessResultParam.setStatusAudit(statusAudit);
        businessResultParam.setDutyPersonalName(dutyPeopleName);

        // 如果角色中不包含超级管理员，则只能查自己参与的和自己录入的
        if (!StringUtils.isEmpty(peopleName)) {
            // 先通过自己的名字和模块代号查询出自己相关的项目ids
            List<String> projectIds = personService.selectOwnPorjietidsByOwnNameAndModel(peopleName, modelId);
            //if (CollectionUtils.isEmpty(projectIds)) { // 如果没有查询到与自己相关的项目信息，返回空集合
            //    return ResponseUtil.okList(new ArrayList<BusinessProject>());
            //}
            // 然后通过项目的ids查询自己的项目
            List<BusinessResult> businessResults = businessResultService.querySelectiveByPojectIds(peopleName, projectIds,businessResultParam,page, limit, sort, order);
            return ResponseUtil.okList(businessResults);
        }
        // 超管可以查询所有
        List<BusinessResult> businessResults = businessResultService.querySelective(businessResultParam,page, limit, sort, order);
        return ResponseUtil.okList(businessResults);
    }


    public Object create(BusinessResultDetail businessResultDetail) {
        // 1. 先生成项目的UUID
        String resultId = AdminStringUtil.get32UUID();
        // 2. 添加项目成员，关连项目UUID，同时找出项目负责人（项目负责人有且只能有一个）
        List<BusinessPerson> personList = businessResultDetail.getPersonList();

        // 记录项目负责人,因为项目中也要添加负责人
        String dutyName = null;
        if (!CollectionUtils.isEmpty(personList)) {
            for (BusinessPerson businessPerson : personList) {
                if (StringUtils.isEmpty(businessPerson.getPersonName())){ // 如果人员名字是空的，就不做处理
                    continue;
                }
                if (Objects.isNull(businessPerson.getPersonDuty())){ // 如果成员角色是空的，也不做处理
                    continue;
                }
                // 判断是不是负责人,如果是就记录下名字
                if (YwcgEnumUtil.PersonDutyNameCode.FIRST.getCode() == businessPerson.getPersonDuty()) {
                    // 如果名字不为空证明已有负责人，把重复的负责人默认置为主要完成人
                    if (dutyName != null) {
                        businessPerson.setPersonDuty(YwcgEnumUtil.PersonDutyNameCode.SECOND.getCode());
                    }else {
                        dutyName = businessPerson.getPersonName();
                    }
                }

                // 设置角色名称
                businessPerson.setPersonDutyName(YwcgEnumUtil.PersonDutyNameCode.getName(businessPerson.getPersonDuty()));
                // 设置基本信息,录入人、录入时间等
                AdminStringUtil.setAdminInsertInfo(businessPerson);
                // 关联项目UUID,设置模块信息以及自己的UUID
                businessPerson.setProjectId(resultId);
                businessPerson.setProjectName(businessResultDetail.getBusinessResult().getResName());
                businessPerson.setPersonId(AdminStringUtil.get32UUID());
                //businessPerson.setOwningModule(YwcgEnumUtil.ModelNameCode.KYP.getCode());
                businessPerson.setOwningModuleName(YwcgEnumUtil.ModelNameCode.getName(businessResultDetail.getBusinessResult().getOwningModule()));
                // 插入成员信息
                personService.insert(businessPerson);
            }
        }

        // 3. 添加附件信息
        // 记录附件名称，存到项目里面
        List<String> fileNames = new ArrayList<>();
        List<ProjectFile> projectFiles = businessResultDetail.getProjectFileList();
        if (projectFiles != null) {

            for (ProjectFile projectFile : projectFiles) {

                if (StringUtils.isEmpty(projectFile.getFileId())){
                    // 没有ID则证明没有上传附件，不保存
                    continue;
                }
                // 设置相关项目id
                projectFile.setProjectId(resultId);
                // 设置基本信息
                AdminStringUtil.setAdminInsertInfo(projectFile);

                if (fileNames.contains(projectFile.getFileName())) {
                    // 如果文件名称已存在，将id拼接上保证唯一
                    projectFile.setFileName(projectFile.getFileId()+"-"+projectFile.getFileName());
                }
                // 记录下文件名称
                fileNames.add(projectFile.getFileName());
                // 插入
                projectFileService.updateByPrimaryKey(projectFile);
            }

        }

        // 4. 设置项目负责人，添加项目信息
        BusinessResult businessResult = businessResultDetail.getBusinessResult();
        AdminStringUtil.setAdminInsertInfo(businessResult);
        businessResult.setDutyPersonalName(StringUtils.isEmpty(dutyName) ? "" : dutyName);
        businessResult.setResId(resultId);
        String businessProjectName = businessProjectService.selectNameByIdIn(businessResult.getResWithProjectId());
        businessResult.setResWithProjectName(businessProjectName);
        businessResult.setStatusAudit(YwcgEnumUtil.StatusAuditCode.noSubmit); // 状态为待提交
        // 设置项目相关文件名称
        businessResult.setResFilesName(JSONUtils.toJSONString(fileNames));
        businessResult.setOwningModuleName(YwcgEnumUtil.ModelNameCode.getName(businessResult.getOwningModule()));
        businessResultService.insert(businessResult);
        return ResponseUtil.ok();
    }

    @Transactional
    public Object delete(BusinessResult businessResult) {
        String resId = businessResult.getResId();
        if (resId == null) {
            return ResponseUtil.badArgument();
        }
        // 1.先判断是不是超级管理员或者是项目负责人,不是超管和项目负责人不能删除该项目
        String userName = AdminCheck.isSuperUser();
        if (StringUtil.isNotEmpty(userName)) { // userName不是空证明不是超管
            if (!userName.equals(businessResult.getDutyPersonalName()) && !userName.equals(businessResult.getAdminName())) { // 不是负责人和录入人无权操作
                return ResponseUtil.unauthz();// 提示无操作权限
            }
            // 判断项目是否是审核中的状态，审核中的项目和审核通过的项目只有超管能编辑和删除
            if (!adBusinessAuditService.canEdit(resId, businessResult.getOwningModule())) { // 如果不能编辑
                return ResponseUtil.fail(999, "审核中或审核通过的项目不能删除，如需删除请联系超管");
            }
        }
        // 2. 如果有权限删除，则删除所有项目成员中间表和项目附件
        // 删除项目附件
        projectFileService.deleteByProjectId(resId);
        // 删除项目成员
        personService.deleteByProjectId(resId);
        // 删除项目成果
        businessResultService.deleteByPrimaryKey(resId);
        return ResponseUtil.ok();
    }

    public Object detail(String resultId) {
        if (StringUtils.isEmpty(resultId)) {
            return ResponseUtil.badArgumentValue(); // 参数值不对
        }
        // 1. 查询项目信息
        BusinessResult businessResult = businessResultService.selectByPrimaryKey(resultId);
        // 2. 查询附件信息
        List<ProjectFile> projectFiles = projectFileService.selectByProjectId(resultId);
        // 3. 查询成员信息
        List<BusinessPerson> personList = personService.selectByProjectId(resultId);

        BusinessResultDetail detail = new BusinessResultDetail();
        detail.setBusinessResult(businessResult);
        detail.setProjectFileList(projectFiles);
        detail.setPersonList(personList);
        return ResponseUtil.ok(detail);
    }




    public Object update(BusinessResultDetail businessResultDetail) {

        BusinessResult businessResult = businessResultDetail.getBusinessResult();
        List<ProjectFile> projectFiles = businessResultDetail.getProjectFileList();
        List<BusinessPerson> personList = businessResultDetail.getPersonList();

        // 判断项目是否已经审核或者正在审核中，正在审核或者审核中的项目只有超管可以修改
        if (!adBusinessAuditService.canEdit(businessResult.getResId(), businessResult.getOwningModule())
                && !StringUtils.isEmpty(AdminCheck.isSuperUser())) {
            return ResponseUtil.fail(999, "审核中或审核通过的项目基本信息不能修改，如需修改请联系超管");
        }

        // 1. 更新成员信息,先全部删除，再插入
        // 记录负责人
        String dutyName = null;
        // 需要先删除所有项目成员
        personService.deleteByProjectId(businessResult.getResId());
        for (BusinessPerson businessPerson : personList) {
            if (YwcgEnumUtil.PersonDutyNameCode.FIRST.getCode() == businessPerson.getPersonDuty()) {
                // 如果名字不为空证明已有负责人，把重复的负责人默认置为主要完成人
                if (dutyName != null) {
                    businessPerson.setPersonDuty(YwcgEnumUtil.PersonDutyNameCode.SECOND.getCode());
                }else {
                    dutyName = businessPerson.getPersonName();
                }
            }
            businessPerson.setProjectId(businessResult.getResId());
            businessPerson.setProjectName(businessResult.getResName());
            businessPerson.setPersonDutyName(YwcgEnumUtil.PersonDutyNameCode.getName(businessPerson.getPersonDuty()));
            if (!StringUtils.isEmpty(businessPerson.getPersonId())) {// 如果有id则执行更新(伪更新)
                AdminStringUtil.setAdminUpdateInfo(businessPerson);
            } else {
                // 没有id则执行插入
                AdminStringUtil.setAdminInsertInfo(businessPerson);
                businessPerson.setPersonId(AdminStringUtil.get32UUID());
                businessPerson.setOwningModule(businessResult.getOwningModule());
                businessPerson.setOwningModuleName(YwcgEnumUtil.ModelNameCode.getName(businessResult.getOwningModule()));
            }
            personService.insert(businessPerson);
        }
        // 2. 更新附件信息,先全部删除，再插入
        projectFileService.deleteByProjectId(businessResult.getResId());
        List<String> fileNames = new ArrayList<>();
        for (ProjectFile projectFile : projectFiles) {

            if (StringUtils.isEmpty(projectFile.getFileId())){
                // 没有ID则证明没有上传附件，不保存
                continue;
            }

            if (fileNames.contains(projectFile.getFileName())) {
                // 如果文件名称已存在，将id拼接上保证唯一
                projectFile.setFileName(projectFile.getFileName() + "-" + projectFile.getFileId());
            }

            projectFile.setProjectId(businessResult.getResId());
            AdminStringUtil.setAdminUpdateInfo(projectFile);

            fileNames.add(projectFile.getFileName());
            projectFileService.updateByPrimaryKey(projectFile);
        }
        // 4. 更新项目信息
        // 判断负责人是否更改
        // 判断项目负责人是否更改和项目附件是否更改
        if (!businessResult.getDutyPersonalName().equals(dutyName)) {
            businessResult.setDutyPersonalName(StringUtils.isEmpty(dutyName) ? "" : dutyName);
        }
        if (!StringUtils.isEmpty(businessResult.getResFilesName()) ||
                !businessResult.getResFilesName().equals(JSONUtils.toJSONString(fileNames))) {
            businessResult.setResFilesName(JSONUtils.toJSONString(fileNames));
        }
        AdminStringUtil.setAdminUpdateInfo(businessResult);
        // 插入依托项目名称
        String businessProjectName = businessProjectService.selectNameByIdIn(businessResult.getResWithProjectId());
        businessResult.setResWithProjectName(businessProjectName);
        businessResult.setOwningModuleName(YwcgEnumUtil.ModelNameCode.getName(businessResult.getOwningModule()));
        // 执行更新
        businessResultService.update(businessResult);
        return ResponseUtil.ok();
    }

    public Object listPerformance(Integer modelId, String peopleName) {
        // 项目成员信息,key是成员角色，value是成员信息
        Map<Integer,List<BusinessPerson>> performanceMap = new HashMap<>();
        // 如果是-1代表查询全部，如果是
        if (modelId == -1){
            for (YwcgEnumUtil.PersonDutyNameCode dutyNameCode : YwcgEnumUtil.PersonDutyNameCode.values()) {
                List<BusinessPerson> personList = personService.selectPerformanceByDuty(dutyNameCode.getCode(), peopleName,null);
                performanceMap.put(dutyNameCode.getCode(),personList);
            }
        }else {
            for (YwcgEnumUtil.PersonDutyNameCode dutyNameCode : YwcgEnumUtil.PersonDutyNameCode.values()) {
                List<BusinessPerson> personList = personService.selectPerformanceByDuty(dutyNameCode.getCode(), peopleName,modelId);
                performanceMap.put(dutyNameCode.getCode(),personList);
            }
        }
        return performanceMap;
    }
}
